package com.kzj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.kzj.dao.*;
import com.kzj.domain.*;
import com.kzj.domain.vo.*;
import com.kzj.global.constant.GlobalConstant;
import com.kzj.global.exception.MyException;
import com.kzj.global.re.Result;
import com.kzj.global.threadLocal.UserThreadLocal;
import com.kzj.global.utils.GlobalUtil;
import com.kzj.global.utils.IdGeneratorUtil;
import com.kzj.global.utils.MatchesUtil;
import com.kzj.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.sun.org.apache.xpath.internal.operations.String;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kzj
 * @since 2023-12-01
 */
@Service
@Slf4j
public class EletiveCourseServiceImpl extends ServiceImpl<ElectiveCourseDao, ElectiveCourse> implements EletiveCourseService {
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    CourseSelectionInformationService courseSelectionInformationService;
    @Autowired
    TeacherService teacherService;
    @Autowired
    MajorDao majorDao;
    @Autowired
    MajorService majorService;
    @Autowired
    StudentDao studentDao;
    @Autowired
    CourseInformationDao courseInformationDao;
    @Autowired
    ClassroomDao classroomDao;
    @Autowired
    ClassroomService classroomService;
    @Autowired
    CourseRestrictedMajorsService courseRestrictedMajorsService;
    @Override
    public Result addCourse(ElectiveCourse electiveCourse) {
        MatchesUtil.objMatches(electiveCourse);
        electiveCourse.setId(IdGeneratorUtil.generatorId(ElectiveCourse.class));
        if(electiveCourse.getAmount()==null)
        {
            electiveCourse.setAmount(electiveCourse.getTotalAmount());
        }
        if(electiveCourse.getTeacherId()==null)
        {
            Teacher user = UserThreadLocal.getUser(Teacher.class);
            electiveCourse.setTeacherId(user.getId());
        }
        if(electiveCourse.getStartWeek()>electiveCourse.getEndWeek())
        {
            throw new MyException(GlobalConstant.PARAMS_START_END_WEEK_ERROR);
        }
        if(!electiveCourse.getType().equals(GlobalConstant.COURSE_TYPE_MAJOR)&&!electiveCourse.getType().equals(GlobalConstant.COURSE_TYPE_OPTIONAL))
        {
            throw new MyException(GlobalConstant.PARAMS_TYPE_ERROR);
        }
        List<CourseRestrictedMajors> courseInformations = courseRestrictedMajorsService.query().eq("course_information_id", electiveCourse.getCourseId()).list();
        if(courseInformations.isEmpty()&&electiveCourse.getType().equals(GlobalConstant.COURSE_TYPE_MAJOR))
        {
            throw new MyException(GlobalConstant.PARAMS_TYPE_ERROR);
        }
        if(electiveCourse.getClassroomId()==null)
        {
            FreeClassroomDTO freeClassroomDTO = new FreeClassroomDTO();
            freeClassroomDTO.setSchooltime(electiveCourse.getSchooltime());
            freeClassroomDTO.setStartWeek(electiveCourse.getStartWeek());
            freeClassroomDTO.setEndWeek(electiveCourse.getEndWeek());
            freeClassroomDTO.setCurriculumTime(electiveCourse.getCurriculumTime());
            List<Classroom> freeClassroom = (List<Classroom>)classroomService.getFreeClassroom(freeClassroomDTO).getData();
            if(freeClassroom.isEmpty())
            {
                throw new MyException(GlobalConstant.NO_FREE_CLASSROOM);
            }
            Collections.shuffle(freeClassroom);
            electiveCourse.setClassroomId(freeClassroom.get(0).getId());
        }
        List<ElectiveCourse> electiveCourses = this.query().eq("teacher_id", electiveCourse.getTeacherId()).list();
        for (ElectiveCourse course : electiveCourses) {
            if(!course.getCurriculumTime().equals(electiveCourse.getCurriculumTime()))
                continue;
            if(!course.getSchooltime().equals(electiveCourse.getSchooltime()))
                    continue;
            if(course.getStartWeek()>electiveCourse.getEndWeek()||course.getEndWeek()<electiveCourse.getStartWeek())
                continue;
            throw new MyException(GlobalConstant.COURSE_TIME_CONFLICT);
        }
        electiveCourse.setCreateDate(LocalDate.now());
        this.save(electiveCourse);
        return Result.success(GlobalConstant.ADD_COURSE_SUCCESS);
    }

    @Override
    public void preheat(String curriculumTime) {
        log.info("预热开始");
        //TODO preheat 定时任务删除key
        List<ElectiveCourse> list = this.query().eq("curriculum_time",curriculumTime).list();
//        Long ttl=GlobalConstant.COURSE_TTL;
        stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                Map<String,List<String>> majorCourse=new HashMap<>();
                for (ElectiveCourse electiveCourse : list) {
                    ElectiveCourseVO courseVO = getElectiveCourseVO(electiveCourse);
                    String jsonString = JSONObject.toJSONString(courseVO);
                    redisConnection.set((GlobalConstant.COURSE_INFO_PREFIX+ electiveCourse.getId()).getBytes(),jsonString.getBytes());
                    redisConnection.set((GlobalConstant.COURSE_AMOUNT_PREFIX+ electiveCourse.getId()).getBytes(),(electiveCourse.getAmount()+"").getBytes());
                    String[] majors= courseVO.getRestrictedMajorIds().split(GlobalConstant.COURSE_RESTRICTED_MAJORS_SPLIT);
                    String[] terms= electiveCourse.getTerm().split(GlobalConstant.COURSE_TERM_SPLIT);
                    for (String term : terms) {
                        for (String s : majors) {
                            String key=GlobalConstant.MAJOR_OPTIONAL_COURSE_ID_PREFIX+s+GlobalConstant.MAJOR_OPTIONAL_COURSE_TERM_PREFIX+term;
                            if(!majorCourse.containsKey(key))
                            {
                                majorCourse.put(key,new ArrayList<>());
                            }
                            //TODO 0 是通选课
                            majorCourse.get(key).add(electiveCourse.getId());
                        }
                    }
                }
                Set<Map.Entry<String, List<String>>> entries = majorCourse.entrySet();
                for (Map.Entry<String, List<String>> entry : entries) {
                    String join = StringUtil.join(entry.getValue(), ",");
                    redisConnection.set(entry.getKey().getBytes(),join.getBytes());
                }
                return null;
            }
        });

    }

    @Override
    public Result getSelfSchedule(Integer term,Integer week) {
        Student user = UserThreadLocal.getUser(Student.class);
        return getSchedule(user.getId(),term,week);
    }
    @Override
    public Result getSchedule(String id, Integer term,Integer week) {
        List<List<ScheduleCourseVO>> scheduleCourseVOListList = getScheduleCourseVOListList(id, term, week);
        String[] time=GlobalConstant.COURSE_CLASS_TIME;
        List<ScheduleMidVO> scheduleMidVOS=new ArrayList<>(6);
        for(int i=1;i<=GlobalConstant.ONE_DAY_MAX_COURSE_AMOUNT;i++)
        {
            List<ScheduleCourseVO> scheduleCourseVOList=scheduleCourseVOListList.get(i-1);
            ScheduleMidVO scheduleMidVO = new ScheduleMidVO();
            scheduleMidVO.setMonday(scheduleCourseVOList.get(0));
            scheduleMidVO.setTuesday(scheduleCourseVOList.get(1));
            scheduleMidVO.setWednesday(scheduleCourseVOList.get(2));
            scheduleMidVO.setThursday(scheduleCourseVOList.get(3));
            scheduleMidVO.setFriday(scheduleCourseVOList.get(4));
            scheduleMidVO.setSaturday(scheduleCourseVOList.get(5));
            scheduleMidVO.setSunday(scheduleCourseVOList.get(6));
            scheduleMidVO.setTime(time[i-1]);
            scheduleMidVOS.add(scheduleMidVO);
        }
        return Result.success(scheduleMidVOS);
    }
    @Override
    public List<List<ScheduleCourseVO>> getScheduleCourseVOListList(String id, Integer term,Integer week)
    {
        List<String> courseIds = courseSelectionInformationService.getCourseIdsByStudentIdAndTerm(id,term);
        List<ElectiveCourseVO> electiveCourseVOS = (List<ElectiveCourseVO>)getElectiveCourseVOByIds(courseIds).getData();
        return getScheduleCourseVOListList(electiveCourseVOS,week);
    }

    @Override
    public List<List<ScheduleCourseVO>> getScheduleCourseVOListListByTeacherId(String teacherId, String curriculumTime, Integer week) {
        List<ElectiveCourse> list = this.query().eq("teacher_id", teacherId).eq("curriculum_time", curriculumTime).list();
        List<ElectiveCourseVO> collect = list.stream().map(item -> getElectiveCourseVO(item)).collect(Collectors.toList());
        return getScheduleCourseVOListList(collect,week);
    }

    @Override
    public Result getTeacherScheduleByTeacherIdAndTerm(String teacherId, String curriculumTime) {
        List<List<ScheduleCourseVO>> scheduleCourseVOListList = getScheduleCourseVOListListByTeacherId(teacherId, curriculumTime, null);
        String[] time=GlobalConstant.COURSE_CLASS_TIME;
        List<ScheduleMidVO> scheduleMidVOS=new ArrayList<>(6);
        for(int i=1;i<=GlobalConstant.ONE_DAY_MAX_COURSE_AMOUNT;i++)
        {
            List<ScheduleCourseVO> scheduleCourseVOList=scheduleCourseVOListList.get(i-1);
            ScheduleMidVO scheduleMidVO = new ScheduleMidVO();
            scheduleMidVO.setMonday(scheduleCourseVOList.get(0));
            scheduleMidVO.setTuesday(scheduleCourseVOList.get(1));
            scheduleMidVO.setWednesday(scheduleCourseVOList.get(2));
            scheduleMidVO.setThursday(scheduleCourseVOList.get(3));
            scheduleMidVO.setFriday(scheduleCourseVOList.get(4));
            scheduleMidVO.setSaturday(scheduleCourseVOList.get(5));
            scheduleMidVO.setSunday(scheduleCourseVOList.get(6));
            scheduleMidVO.setTime(time[i-1]);
            scheduleMidVOS.add(scheduleMidVO);
        }
        return Result.success(scheduleMidVOS);
    }

    @Override
    public Result getTeacherCurrentTermScheduleByTeacherId(String teacherId) {
        return getTeacherScheduleByTeacherIdAndTerm(teacherId,GlobalUtil.getCurrentTerm());
    }

    @Override
    public Result getTeacherNextTermScheduleByTeacherId(String teacherId) {
        return getTeacherScheduleByTeacherIdAndTerm(teacherId,GlobalUtil.getTagTerm(1));
    }

    @Override
    public Result getArrangeCourseList(String teacherId, String curriculumTime) {
        List<ElectiveCourseVO> collect = this.query().eq("teacher_id", teacherId).eq("curriculum_time", curriculumTime).list().stream().map(item -> getElectiveCourseVO(item)).collect(Collectors.toList());
        String[] dayOfWeekList=GlobalConstant.DAY_OF_WEEK_LIST;
        String[] timeOfDayList=GlobalConstant.TIME_OF_DAY_LIST;
        List<OptionalCourseVO> list=new ArrayList<>();
        String[] split1 = curriculumTime.split(GlobalConstant.CURRICULUM_TIME_SPLIT);
        String year=split1[0];
        String term=split1[1];
        for (int i = 0; i < collect.size(); i++) {
            ElectiveCourseVO electiveCourseVO=collect.get(i);
            String[] split = electiveCourseVO.getSchooltime().split(GlobalConstant.COURSE_SCHOOL_TIME_SPLIT);
            Integer dayOfWeek=Integer.valueOf(split[0]);
            Integer timeOfDay=Integer.valueOf(split[1]);
            list.add(OptionalCourseVO.builder()
                            .id((i+1)+"")
                            .lesson(electiveCourseVO.getCourseName())
                            .number(electiveCourseVO.getId())
                            .start(electiveCourseVO.getStartWeek().toString())
                            .end(electiveCourseVO.getEndWeek().toString())
                            .day(dayOfWeekList[dayOfWeek-1])
                            .time(timeOfDayList[timeOfDay-1])
                            .site(electiveCourseVO.getTotalAmount().toString())
                            .major(electiveCourseVO.getRestrictedMajorNames())
                            .year(year)
                            .term(term.equals(GlobalConstant.UPPER_TERM_FLAG)?GlobalConstant.UPPER_TERM:GlobalConstant.DOWN_TERM)
                    .build());
        }
        return Result.success(list);
    }

    @Override
    public Result getArrangeCourseList(String teacherId, LocalDate startDate,LocalDate endDate) {
        List<ElectiveCourseVO> collect = this.query().eq("teacher_id", teacherId).ge(startDate!=null,"create_date", startDate).le(endDate!=null,"create_date",endDate).list().stream().map(item -> getElectiveCourseVO(item)).collect(Collectors.toList());
        String[] dayOfWeekList=GlobalConstant.DAY_OF_WEEK_LIST;
        String[] timeOfDayList=GlobalConstant.TIME_OF_DAY_LIST;
        List<OptionalCourseVO> list=new ArrayList<>();
        for (int i = 0; i < collect.size(); i++) {
            String[] split1 = collect.get(i).getCurriculumTime().split(GlobalConstant.CURRICULUM_TIME_SPLIT);
            String year=split1[0];
            String term=split1[1];
            ElectiveCourseVO electiveCourseVO=collect.get(i);
            String[] split = electiveCourseVO.getSchooltime().split(GlobalConstant.COURSE_SCHOOL_TIME_SPLIT);
            Integer dayOfWeek=Integer.valueOf(split[0]);
            Integer timeOfDay=Integer.valueOf(split[1]);
            list.add(OptionalCourseVO.builder()
                    .id((i+1)+"")
                    .lesson(electiveCourseVO.getCourseName())
                    .number(electiveCourseVO.getId())
                    .start(electiveCourseVO.getStartWeek().toString())
                    .end(electiveCourseVO.getEndWeek().toString())
                    .day(dayOfWeekList[dayOfWeek-1])
                    .time(timeOfDayList[timeOfDay-1])
                    .site(electiveCourseVO.getTotalAmount().toString())
                    .major(electiveCourseVO.getRestrictedMajorNames())
                    .year(year)
                    .term(term.equals(GlobalConstant.UPPER_TERM_FLAG)?GlobalConstant.UPPER_TERM:GlobalConstant.DOWN_TERM)
                    .build());
        }
        return Result.success(list);
    }

    @Override
    public void addAmountByElectiveCourseVO(ElectiveCourseVO electiveCourseVO) {
        String key=GlobalConstant.COURSE_AMOUNT_PREFIX+electiveCourseVO.getId();
        String amount = stringRedisTemplate.opsForValue().get(key);
        electiveCourseVO.setAmount(Integer.valueOf(amount));
    }

    public List<List<ScheduleCourseVO>> getScheduleCourseVOListList(List<ElectiveCourseVO> collect,Integer week)
    {
        List<List<ScheduleCourseVO>> scheduleCourseVOListList=new ArrayList<>(6);
        for(int i=1;i<=GlobalConstant.ONE_DAY_MAX_COURSE_AMOUNT;i++)
        {
            List<ScheduleCourseVO> scheduleCourseVOList = getScheduleCourseVOList(collect, week, i);
            scheduleCourseVOListList.add(scheduleCourseVOList);
        }
        return scheduleCourseVOListList;
    }


    public ElectiveCourseVO getMeetTheConditionsCourseVO(List<ElectiveCourseVO> electiveCourseVOS, Integer week, Integer dayOfWeek, Integer timeOfDay)
    {
        for (ElectiveCourseVO electiveCourseVO : electiveCourseVOS) {
            if(week!=null)
                if(electiveCourseVO.getStartWeek()>week|| electiveCourseVO.getEndWeek()<week)
                    continue;
            String[] split = electiveCourseVO.getSchooltime().split(GlobalConstant.COURSE_SCHOOL_TIME_SPLIT);
            Integer courseDayOfWeek=Integer.valueOf(split[0]);
            Integer courseTimeOfDay=Integer.valueOf(split[1]);
            if(courseDayOfWeek!=dayOfWeek||courseTimeOfDay!=timeOfDay) continue;
            return electiveCourseVO;
        }
        return null;
    }
    public List<ScheduleCourseVO> getScheduleCourseVOList(List<ElectiveCourseVO> electiveCourseVOS, Integer week, Integer timeOfDay)
    {
        List<ScheduleCourseVO> list=new ArrayList<>();
        for(int i=1;i<=7;i++)
        {
            ElectiveCourseVO electiveCourseVO = getMeetTheConditionsCourseVO(electiveCourseVOS, week, i, timeOfDay);
            list.add(getScheduleCourseVO(electiveCourseVO));
        }
        return list;
    }
    @Override
    public Result getTotalSchedule(String id, Integer term) {
        List<CourseSelectionInformation> list = courseSelectionInformationService.query().like("select_term", term).eq("student_id", id).list();
        List<String> courseIds = list.stream().map(item -> item.getElectiveCourseId()).collect(Collectors.toList());
        List<ElectiveCourseVO> electiveCourseVOS = (List<ElectiveCourseVO>)getElectiveCourseVOByIds(courseIds).getData();
        String[] time=GlobalConstant.COURSE_CLASS_TIME;
        List<TotalScheduleMidVO> totalScheduleMidVOS =new ArrayList<>(6);
        for(int i=1;i<=GlobalConstant.ONE_DAY_MAX_COURSE_AMOUNT;i++)
        {
            TotalScheduleMidVO totalScheduleMidVO = getTotalScheduleMidVO(electiveCourseVOS, i);
            totalScheduleMidVO.setTime(time[i-1]);
            totalScheduleMidVOS.add(totalScheduleMidVO);
        }
        return Result.success(totalScheduleMidVOS);
    }
    public List<ElectiveCourseVO> getMeetTheConditionsCourseVOS(List<ElectiveCourseVO> electiveCourseVOS, Integer dayOfWeek, Integer timeOfDay)
    {
        List<ElectiveCourseVO> list=new ArrayList<>();
        for (ElectiveCourseVO electiveCourseVO : electiveCourseVOS) {
            String[] split = electiveCourseVO.getSchooltime().split(GlobalConstant.COURSE_SCHOOL_TIME_SPLIT);
            Integer courseDayOfWeek=Integer.valueOf(split[0]);
            Integer courseTimeOfDay=Integer.valueOf(split[1]);
            if(courseDayOfWeek!=dayOfWeek||courseTimeOfDay!=timeOfDay) continue;
            list.add(electiveCourseVO);
        }
        return list;
    }
    public TotalScheduleMidVO getTotalScheduleMidVO(List<ElectiveCourseVO> electiveCourseVOS, Integer timeOfDay)
    {
        TotalScheduleMidVO totalScheduleMidVO = new TotalScheduleMidVO();
        List<ScheduleCourseVO> scheduleCourseVOS = getMeetTheConditionsCourseVOS(electiveCourseVOS, 1, timeOfDay).stream().map(this::getScheduleCourseVO).collect(Collectors.toList());
        totalScheduleMidVO.setMonday(scheduleCourseVOS);
        scheduleCourseVOS = getMeetTheConditionsCourseVOS(electiveCourseVOS, 2, timeOfDay).stream().map(this::getScheduleCourseVO).collect(Collectors.toList());
        totalScheduleMidVO.setTuesday(scheduleCourseVOS);
        scheduleCourseVOS = getMeetTheConditionsCourseVOS(electiveCourseVOS, 3, timeOfDay).stream().map(this::getScheduleCourseVO).collect(Collectors.toList());
        totalScheduleMidVO.setWednesday(scheduleCourseVOS);
        scheduleCourseVOS = getMeetTheConditionsCourseVOS(electiveCourseVOS, 4, timeOfDay).stream().map(this::getScheduleCourseVO).collect(Collectors.toList());
        totalScheduleMidVO.setThursday(scheduleCourseVOS);
        scheduleCourseVOS = getMeetTheConditionsCourseVOS(electiveCourseVOS, 5, timeOfDay).stream().map(this::getScheduleCourseVO).collect(Collectors.toList());
        totalScheduleMidVO.setFriday(scheduleCourseVOS);
        scheduleCourseVOS = getMeetTheConditionsCourseVOS(electiveCourseVOS, 6, timeOfDay).stream().map(this::getScheduleCourseVO).collect(Collectors.toList());
        totalScheduleMidVO.setSaturday(scheduleCourseVOS);
        scheduleCourseVOS = getMeetTheConditionsCourseVOS(electiveCourseVOS, 7, timeOfDay).stream().map(this::getScheduleCourseVO).collect(Collectors.toList());
        totalScheduleMidVO.setSunday(scheduleCourseVOS);
        return totalScheduleMidVO;
    }
    public ScheduleCourseVO getScheduleCourseVO(ElectiveCourseVO electiveCourseVO)
    {
        return BeanUtil.copyProperties(electiveCourseVO, ScheduleCourseVO.class);
    }
    @Override
    public Result getElectiveCourseVOByIds(List<String> ids) {
        List<ElectiveCourseVO> re=new ArrayList<>(ids.size());
        List<String> subIds=new ArrayList<>();
        for (String id : ids) {
            String s = stringRedisTemplate.opsForValue().get(GlobalConstant.COURSE_INFO_PREFIX + id);
            if(s!=null)
            {
                JSONObject jsonObject =(JSONObject) JSONObject.parse(s);
                ElectiveCourseVO c = jsonObject.toJavaObject(ElectiveCourseVO.class);
                re.add(c);
            }
            else{
                subIds.add(id);
            }
        }
        if(subIds.size()>0)
        {
            List<ElectiveCourseVO> electiveCourseVOS = this.query().in("id", subIds).list().stream().map(this::getElectiveCourseVO).collect(Collectors.toList());
            stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                    for (ElectiveCourseVO electiveCourseVO : electiveCourseVOS) {
                String key=GlobalConstant.COURSE_INFO_PREFIX+ electiveCourseVO.getId();
                String json=JSONObject.toJSONString(electiveCourseVO);
                redisConnection.setEx(key.getBytes(),GlobalConstant.COURSE_TTL,json.getBytes());
                }
                    return null;
                }
            });
            re.addAll(electiveCourseVOS);
        }
        return Result.success(re);
    }
    @Override
    public Result getElectiveCourseVOByIdAndTerm(String id, Integer term) {
        List<CourseSelectionInformation> courseSelectionInformations = courseSelectionInformationService.query().eq("student_id", id).list();
        List<String> courseIds = courseSelectionInformations.stream().map(item -> item.getElectiveCourseId()).collect(Collectors.toList());
        List<ElectiveCourseVO> electiveCourseVOS = (List<ElectiveCourseVO>)getElectiveCourseVOByIds(courseIds).getData();
        electiveCourseVOS = electiveCourseVOS.stream().filter(new Predicate<ElectiveCourseVO>() {
            @Override
            public boolean test(ElectiveCourseVO electiveCourseVO) {
                return electiveCourseVO.getTerm().contains(term.toString());
            }
        }).collect(Collectors.toList());
        return Result.success(electiveCourseVOS);
    }

    @Override
    public Result getMeetTheConditionsCourseByMajorIdAndTerm(String majorId,Integer term) {
        String key=GlobalConstant.MAJOR_OPTIONAL_COURSE_ID_PREFIX+majorId+GlobalConstant.MAJOR_OPTIONAL_COURSE_TERM_PREFIX+term;
        String key0=GlobalConstant.MAJOR_OPTIONAL_COURSE_ID_PREFIX+GlobalConstant.COURSE_RESTRICTED_MAJORS_GENERAL_ELECTIVE_COURSE+GlobalConstant.MAJOR_OPTIONAL_COURSE_TERM_PREFIX+term;
        String s = stringRedisTemplate.opsForValue().get(key);
        String s0 = stringRedisTemplate.opsForValue().get(key0);
        s+=","+s0;
        String[] courseIds = s.split(",");
        List<OptionalCourseVO> list=new ArrayList<>();
        for (int i = 0; i < courseIds.length; i++) {
            String courseId=courseIds[i];
            String json =stringRedisTemplate.opsForValue().get(GlobalConstant.COURSE_INFO_PREFIX + courseId);
            String amount = stringRedisTemplate.opsForValue().get(GlobalConstant.COURSE_AMOUNT_PREFIX + courseId);
            JSONObject jsonObject = (JSONObject)JSONObject.parse(json);
            ElectiveCourseVO electiveCourseVO = jsonObject.toJavaObject(ElectiveCourseVO.class);
            OptionalCourseVO build = OptionalCourseVO.builder()
                    .id(""+(i+1))
                    .lesson(electiveCourseVO.getCourseName())
                    .number(electiveCourseVO.getId())
//                    .teacher(electiveCourseVO.getTeacherName())
                    .start(electiveCourseVO.getStartWeek()+"周")
                    .end(electiveCourseVO.getEndWeek()+"周")
                    .site(electiveCourseVO.getTotalAmount().toString())
                    .remainder(Integer.valueOf(amount))
                    .build();
            list.add(build);
        }
        for (String courseId : courseIds) {

        }
        return Result.success(list);
    }

    @Override
    public Result getSelfMeetTheConditionsCourse() {
        StudentVO user = UserThreadLocal.getUser(StudentVO.class);
        Integer nextTerm= GlobalUtil.getStudentTermByDateOfEnrollment(user.getDateOfEnrollment())+1;
        return getMeetTheConditionsCourseByMajorIdAndTerm(user.getMajorId(),nextTerm);
    }

    @Override
    public Result getMeetTheConditionsCourseByStudentId(String studentId) {
        Student student = studentDao.selectById(studentId);
        Integer nextTerm= GlobalUtil.getStudentTermByDateOfEnrollment(student.getDateOfEnrollment())+1;
        return getMeetTheConditionsCourseByMajorIdAndTerm(student.getMajorId(),nextTerm);
    }

    public ElectiveCourseVO getElectiveCourseVO(ElectiveCourse electiveCourse)
    {
        String[] split = electiveCourse.getSchooltime().split(GlobalConstant.COURSE_SCHOOL_TIME_SPLIT);
        Integer dayOfWeek=Integer.valueOf(split[0]);
        Integer timeOfDay=Integer.valueOf(split[1]);
        ElectiveCourseVO electiveCourseVO =BeanUtil.copyProperties(electiveCourse, ElectiveCourseVO.class);
        TeacherVO teacherVO = (TeacherVO)teacherService.getTeacherById(electiveCourse.getTeacherId()).getData();
        CourseInformation courseInformation = courseInformationDao.selectById(electiveCourse.getCourseId());
        Classroom classroom = classroomDao.selectById(electiveCourse.getClassroomId());
        String[] dayOfWeekList=GlobalConstant.DAY_OF_WEEK_LIST;
        String[] timeOfDayList=GlobalConstant.TIME_OF_DAY_LIST;
        String restrictedMajorIds=courseRestrictedMajorsService.getRestrictedMajorsByCourseId(courseInformation.getId());
        List<Major> majorList = majorService.query().in("id", restrictedMajorIds.split(",")).last("order by field(id," + GlobalUtil.getHandlerList(Arrays.asList(restrictedMajorIds.split(","))) + ")").list();
        List<String> collect = majorList.stream().map(item -> item.getName()).collect(Collectors.toList());
        electiveCourseVO.setCourseName(courseInformation.getName());
        electiveCourseVO.setRestrictedMajorNames(StringUtil.join(collect,","));
        electiveCourseVO.setRestrictedMajorIds(restrictedMajorIds);
        electiveCourseVO.setTeacherName(teacherVO.getName());
        electiveCourseVO.setClassroomName(classroom.getName());
        electiveCourseVO.setDayOfWeek(dayOfWeekList[dayOfWeek-1]);
        electiveCourseVO.setTimeOfDay(timeOfDayList[timeOfDay-1]);
        return electiveCourseVO;
    }


}
